#pragma once
#include "Connection.hpp"
#include "Log.hpp"
#include <functional>

using func_t = std::function<std::string(std::string &)>;
using namespace LogModule;

class IOServer : public Connection
{
public:
    IOServer(int fd, InetAddr &client)
    {
        SetSockfd(fd);
        SetInetAddr(client);
        SetEvent(EPOLLIN | EPOLLET);
        SetNonBlock();
    }

    virtual void Recver() override
    {
        while (true)
        {
            char buffer[1024];
            int n = read(_sockfd, buffer, sizeof(buffer) - 1);

            if (n > 0)
            {
                buffer[n] = 0;
                _inbuffer += buffer;
            }
            else if (n == 0)
            {
                LOG(LogLevel::DEBUG) << "写端关闭，退出成功";
                GetOwner()->DeleteConnection(_sockfd);
                return;
            }
            else
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                {
                    LOG(LogLevel::DEBUG) << "read done";
                    break;
                }
                else if (errno == EINTR)
                {
                    LOG(LogLevel::DEBUG) << "read intr by signal, continue";
                    continue;
                }
                else
                {
                    LOG(LogLevel::WARNING) << "read error ... Ignore";
                    Excepter();
                    return;
                }
            }
        }

        std::cout << "from:" << _inet_addr.Addr() << " recv: " << _inbuffer;

        // 处理读取信息
        handle();

        if (_outbuffer.size())
            Sender();
    }

    void handle()
    {
        // // 简单返回
        // std::string result = "echo #";
        // result += _inbuffer;
        // _inbuffer.clear();
        // _outbuffer = result;

        // std::cout << "返回序列：" << std::endl
        //           << _outbuffer;
        // 添加应答信息
        std::string result;
        if (_handle_message)
            result = _handle_message(_inbuffer);
        _outbuffer += result;
    }

    void RegisterHandleMessage(func_t handle_message)
    {
        _handle_message = handle_message;
    }

    virtual void Sender() override
    {

        while (true)
        {
            int n = write(_sockfd, _outbuffer.c_str(), _outbuffer.size());
            if (n > 0)
            {
                _outbuffer.erase(0, n);
            }
            else if (n == 0)
            {
                break;
            }
            else
            {
                if (errno == EWOULDBLOCK)
                {
                    LOG(LogLevel::DEBUG) << "write done";
                    // 缓存区写满
                    break;
                }
                else if (errno == EINTR)
                {
                    LOG(LogLevel::DEBUG) << "write intr by signal, continue";
                    continue;
                }
                else
                {
                    LOG(LogLevel::WARNING) << "write error ... Ignore";
                    Excepter();
                    return;
                }
            }
        }

        if (_outbuffer.size())
        {
            GetOwner()->EnableReadWrite(_sockfd, true, true);
        }
        else
        {
            GetOwner()->EnableReadWrite(_sockfd, true, false);
        }
    }

    virtual void Excepter() override
    {
        LOG(LogLevel::DEBUG) << "客户端连接可能结束，进行异常处理: " << _sockfd;
        // 移除内核的关心
        GetOwner()->DeleteConnection(_sockfd);
    }

private:
    func_t _handle_message;
};
